/*
 * Created by Jaren at 2023/6/1 15:20
 */
import 'package:binary/src/boxed_int.dart';
import 'dart:typed_data';

import 'package:inmotion_protocol/base/vehicle_data.dart';
import 'package:inmotion_protocol/common/compact.dart';
import 'package:inmotion_protocol/common/exceptions.dart';
import 'package:inmotion_protocol/common/product_model.dart';
import 'package:inmotion_protocol/common/product_version.dart';
import 'package:inmotion_protocol/lorin/bean/base/real_time_info.dart';
import 'package:inmotion_protocol/lorin/bean/base/vehicle_real_time_info.dart';
import 'package:inmotion_protocol/lorin/bean/euc/v13/v13_real_time_data.dart';
import 'package:inmotion_protocol/util/byte_util.dart';

class AllV14RealTimeData extends AllRealTimeData<V14RealTimeInfo,
    V14RealTimeState, V14RealTimeError> {
  AllV14RealTimeData(V14RealTimeInfo realTimeInfo,
      V14RealTimeState realTimeState, V14RealTimeError realTimeError)
      : super(realTimeInfo, realTimeState, realTimeError);
}


class V14VehicleSynthesizeRealTimeInfo extends VehicleSynthesizeRealTimeInfo<CommonVehicleRealTimeInfo, V14RealTimeState, V14RealTimeError> {
  V14VehicleSynthesizeRealTimeInfo(CommonVehicleRealTimeInfo commonVehicleRealTimeInfo, V14RealTimeState realTimeState, V14RealTimeError realTimeError) : super(commonVehicleRealTimeInfo, realTimeState, realTimeError);
}

/// 实时信息
class V14RealTimeInfo extends V13RealTimeInfo {
  V14RealTimeInfo(super.model, super.version);

  @override
  String toString() {
    return "V14RealTimeInfo{${super.toString()}}";
  }
}

/// 实时状态
class V14RealTimeState extends V13RealTimeState {
  V14RealTimeState(ProductModel model, VersionWrapper version)
      : super(model, version);
}

/// 实时故障和警告
class V14RealTimeError extends V13RealTimeError {
  Uint4 lowTemperatureAndLowBatteryState = Uint4.zero; // 低温低电警告

  V14RealTimeError(ProductModel model, VersionWrapper version)
      : super(model, version);

  @override
  void initCompact() {
    compact = _DefaultV14RealTimeError();
  }

  @override
  String toString() {
    return 'V14RealTimeError{ ${super.toString()}, riskBehaviourState: $riskBehaviourState, lowTemperatureAndLowBatteryState: $lowTemperatureAndLowBatteryState}';
  }
}

class _DefaultV14RealTimeError
    extends DefaultV13RealTimeErrorDelegate<V14RealTimeError> {
  @override
  void fromBytes(V14RealTimeError output, Uint8ClampedList bytes, int offset) {
    super.fromBytes(output, bytes, offset);

    offset += 8;

    output.lowTemperatureAndLowBatteryState =
        ByteUtil.bitValue(bytes[offset], 0, 1);
  }
}

class V14BatteryRealTimeInfo extends AbsBatteryRealTimeInfo {
  V14SingleBatteryRealTimeInfo? _battery1;
  V14SingleBatteryRealTimeInfo? _battery2;
  V14SingleBatteryRealTimeInfo? _battery3;
  V14SingleBatteryRealTimeInfo? _battery4;

  V14BatteryRealTimeInfo(ProductModel model, VersionWrapper version)
      : super(model, version);

  @override
  void initCompact() {
    compact = _DefaultV14BatteryRealTimeInfo(model, version);
  }

  get battery1 {
    if (_battery1 == null)
      throw ProtocolParseException(
          "Unexpected exception. Please call [fromBytes] to gen battery info first!");
    return _battery1!;
  }

  get battery2 {
    if (_battery2 == null)
      throw ProtocolParseException(
          "Unexpected exception. Please call [fromBytes] to gen battery info first!");
    return _battery2!;
  }

  get battery3 {
    if (_battery3 == null)
      throw ProtocolParseException(
          "Unexpected exception. Please call [fromBytes] to gen battery info first!");
    return _battery3!;
  }

  get battery4 {
    if (_battery4 == null)
      throw ProtocolParseException(
          "Unexpected exception. Please call [fromBytes] to gen battery info first!");
    return _battery4!;
  }

  @override
  String toString() {
    return 'V14BatteryRealTimeInfo{_battery1: $_battery1, _battery2: $_battery2, _battery3: $_battery3, _battery4: $_battery4}';
  }
}

class _DefaultV14BatteryRealTimeInfo extends Compact<V14BatteryRealTimeInfo> {
  final ProductModel _model;
  final VersionWrapper _versionWrapper;

  _DefaultV14BatteryRealTimeInfo(this._model, this._versionWrapper);

  @override
  void fromBytes(
      V14BatteryRealTimeInfo output, Uint8ClampedList bytes, int offset) {
    output._battery1 = V14SingleBatteryRealTimeInfo(_model, _versionWrapper);
    output._battery1!.fromBytes(bytes, offset);
    offset += output._battery1!.length();
    output._battery2 = V14SingleBatteryRealTimeInfo(_model, _versionWrapper);
    output._battery2!.fromBytes(bytes, offset);
    offset += output._battery2!.length();
    output._battery3 = V14SingleBatteryRealTimeInfo(_model, _versionWrapper);
    output._battery3!.fromBytes(bytes, offset);
    offset += output._battery3!.length();
    output._battery4 = V14SingleBatteryRealTimeInfo(_model, _versionWrapper);
    output._battery4!.fromBytes(bytes, offset);
  }

  @override
  int length() {
    return 32;
  }
}

class V14SingleBatteryRealTimeInfo extends V13SingleBatteryRealTimeInfo {
  V14SingleBatteryRealTimeInfo(ProductModel model, VersionWrapper version)
      : super(model, version);

  @override
  String toString() {
    return 'V14SingleBatteryRealTimeInfo{${super.toString()}';
  }
}
